import json
import os
import time
import base64
import io

import requests
from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from PIL import Image

from SAID import settings
from django.apps import apps


# Create your views here.


def index(request):
    return render(request,'index.html')


def interaction(request):
    return render(request,'interact.html')

#  生成智能文本
def process_text(request):
    if request.method == "POST":
        text = request.POST['text'].strip()
        if not text:
            return JsonResponse({'status':'error','message':'Please enter a text.'})

        time.sleep(1)
        return JsonResponse({
            'status':'success',
            'message':'处理完成',
            'original_text':text,
            'result':'有效',
        })

    return JsonResponse({'status':'error','message':'please use post'})

# 保存文件到json文件中
def save_to_json_file(data, filename='guidance_data.json'):
    """
    将数据追加到JSON文件中，支持增量更新
    假设data目录和文件已存在
    """
    APP_NAME = 'intelligence_interaction'
    DATA_DIR = 'data'
    TEMPLATES_DIR = 'templates'
    STATIC_DIR = 'static'

    # 获取子应用的data目录路径
    try:
        app_path = apps.get_app_config(APP_NAME).path
    except LookupError:
        app_path = os.path.join(settings.BASE_DIR, APP_NAME)

    file_path = os.path.join(app_path, TEMPLATES_DIR, STATIC_DIR, DATA_DIR, filename)
    os.makedirs(os.path.dirname(file_path), exist_ok=True)

    # 读取现有数据
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            existing_data = json.load(f)
    except FileNotFoundError:
        existing_data = []
    except json.JSONDecodeError:
        existing_data = []

    # 添加新数据并保存
    existing_data.append(data)
    with open(file_path, 'w', encoding='utf-8') as f:
        json.dump(existing_data, f, ensure_ascii=False, indent=2)

    return file_path

@require_POST
def generate_guidance(request):
    print("Request method:", request.method)
    print("Request content type:", request.content_type)
    print("Request POST data:", request.POST)
    try:
        start_time = time.time()
        misconception = request.POST.get('misconception')
        records = get_records()
        if misconception in records:
            return JsonResponse({
                'success': True,
                'response_time': int((time.time() - start_time) * 1000),  # 返回响应时间
                'guidance_text': records[misconception]['api_response']['output']  # 大模型生成的引导文本
            })
        else:
            # 提取必要的参数
            event = request.POST.get('event')
            guideline = request.POST.get('guideline')

            # 参数验证
            if not all([event, guideline, misconception]):
                return JsonResponse({
                    'error': 'Missing required parameters: event, guideline, and misconception are required.'
                }, status=400)

            # 准备调用外部API
            api_url = 'http://localhost:25602/generate-guidance/invoke'
            payload = {
                "input": {
                    "event": event,
                    "guideline": guideline,
                    "misconception": misconception
                }
            }

            # 记录开始时间，用于计算响应时间
            start_time = time.time()
            # 发送请求到Ollama API
            response = requests.post(api_url, json=payload)

            # 计算响应时间（毫秒）
            response_time = int((time.time() - start_time) * 1000)

            # 构建存储数据对象
            log_data = {
                'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
                'request': {
                    'event': event,
                    'guideline': guideline,
                    'misconception': misconception
                },
                'response_time': response_time,
                'api_response': {
                    'status_code': response.status_code,
                    'output': response.json().get('output', '') if response.status_code == 200 else None,
                    'details': response.text if response.status_code != 200 else None #失败详情
                }
            }

            # 保存数据到JSON文件
            save_to_json_file(log_data)

            # 处理API响应
            if response.status_code == 200:
                result = response.json()
                return JsonResponse({
                    'success': True,
                    'response_time': response_time,  # 返回响应时间
                    'guidance_text': result.get('output', '')  # 大模型生成的引导文本
                })
            else:
                return JsonResponse({
                    'success': False,
                    'error': f'模型API调用失败: HTTP {response.status_code}',
                    'details': response.text
                }, status=500)

    except Exception as e:
        return JsonResponse({
            'success': False,
            'error': f'服务器内部错误: {str(e)}'
        }, status=500)

def get_records():
    results = get_results()
    records = {}
    for res in results:
        records[res["request"]["misconception"]] = res
    return records

def get_results():
    """从 result.json 文件读取所有结果"""
    json_file_path = os.path.join(
        os.path.dirname(__file__),
        'templates',
        'static',
        'data',
        'guidance_data.json'
    )
    if os.path.exists(json_file_path):
        try:
            with open(json_file_path, 'r', encoding='utf-8') as f:
                 return json.load(f)
        except:
            return []
# 获取文本历史记录
def get_results_from_json(request):
    return JsonResponse({'results': get_results()})




    
# 获取图片历史记录
def get_image_results_from_json(request):
    """从 t2i-recoreds.json 文件获取图片历史记录"""
    try:
        algorithm_dir = os.path.join(os.path.dirname(__file__), 'algorithm')
        json_file_path = os.path.join(algorithm_dir, 't2i-recoreds.json')
        
        if os.path.exists(json_file_path):
            with open(json_file_path, 'r', encoding='utf-8') as f:
                records = json.load(f)
            
            # 转换数据格式以匹配前端期望的结构
            formatted_results = []
            
            # 检查records是字典还是列表，兼容两种格式
            if isinstance(records, dict):
                # 新格式：字典
                for opinion, record in records.items():
                    formatted_result = {
                        'timestamp': record.get('timestamp', time.strftime('%Y-%m-%d %H:%M:%S')),
                        'request': {
                            'event': record.get('event', opinion),
                            'guideline': record.get('guideline', '图片引导'),
                            'misconception': opinion
                        },
                        'image_data': {
                            'image': record.get('image', ''),
                            'text': record.get('text', ''),
                            'image_source': 'local'
                        }
                    }
                    formatted_results.append(formatted_result)
            else:
                # 旧格式：列表（兼容性处理）
                for record in records:
                    if isinstance(record, dict) and 'opinion' in record:
                        formatted_result = {
                            'timestamp': record.get('timestamp', time.strftime('%Y-%m-%d %H:%M:%S')),
                            'request': {
                                'event': record.get('event', record.get('opinion', '未知事件')),
                                'guideline': record.get('guideline', '图片引导'),
                                'misconception': record.get('opinion', '')
                            },
                            'image_data': {
                                'image': record.get('image', ''),
                                'text': record.get('text', ''),
                                'image_source': 'local'
                            }
                        }
                        formatted_results.append(formatted_result)
            
            return JsonResponse({'results': formatted_results})
        else:
            return JsonResponse({'results': []})
            
    except Exception as e:
        print(f"获取图片历史记录失败: {str(e)}")
        return JsonResponse({'results': [], 'error': str(e)})




def image_generator_page(request):
    """渲染图片生成器页面"""
    return render(request, 'image_generator.html')

# 图片生成器页面
@csrf_exempt
@require_POST
def generate_image_from_text(request):
    """
    接收前端文字，调用generate_guidance接口获取响应，再生成图片
    """
    print("Request method:", request.method)
    print("Request content type:", request.content_type)
    print("Request POST data:", request.POST)
    
    try:
        # 获取前端发送的数据
        event = request.POST.get('event', '').strip()
        guideline = request.POST.get('guideline', '').strip()
        misconception = request.POST.get('misconception', '').strip()
        
        print(f"接收到的数据: event={event}, guideline={guideline}, misconception={misconception}")
        
        if not all([event, guideline, misconception]):
            return JsonResponse({
                'success': False,
                'error': '请提供完整的事件主题、引导方向和用户观点'
            }, status=400)
        
        # 首先尝试从JSON文件中检索匹配的opinion
        img_base64 = None
        is_fallback_image = False
        image_source = "local"  # 标记图片来源
        
        try:
            # 读取JSON文件
            algorithm_dir = os.path.join(os.path.dirname(__file__), 'algorithm')
            json_file_path = os.path.join(algorithm_dir, 't2i-recoreds.json')
            
            if os.path.exists(json_file_path):
                with open(json_file_path, 'r', encoding='utf-8') as f:
                    records = json.load(f)
                
                # 直接使用opinion作为key进行O(1)查找
                if misconception in records:
                    matched_record = records[misconception]
                    # 找到匹配的记录，直接读取对应图片
                    image_path = matched_record.get('image', '')
                    if image_path:
                        # 构建完整的图片路径
                        full_image_path = os.path.join(algorithm_dir, image_path.replace('./', ''))
                        if os.path.exists(full_image_path):
                            # 读取图片文件并转换为base64
                            with open(full_image_path, 'rb') as img_file:
                                img_bytes = img_file.read()
                                img_base64 = base64.b64encode(img_bytes).decode()
                                guidance_text = matched_record.get('text', '')
                                print(f"从本地文件找到匹配图片: {image_path}")
                                print(f"对应的提示词: {prompt}")
                        else:
                            print(f"图片文件不存在: {full_image_path}")
                    else:
                        print("匹配记录中没有图片路径")
                else:
                    print(f"未找到匹配的用户观点: {misconception}")
            else:
                print("JSON文件不存在")
                
        except Exception as local_error:
            print(f"检索本地文件失败: {str(local_error)}")
        
        # 如果没有找到本地图片，则调用大模型生成
        if not img_base64:
            print("本地未找到匹配图片，开始调用大模型生成...")
            image_source = "generated"
            
            # 第一步：调用generate_guidance接口生成引导内容
            try:
                guidance_url = "http://localhost:25602/generate-guidance/invoke"
                guidance_payload = {
                    "input": {
                        "event": event,
                        "guideline": guideline,
                        "misconception": misconception
                    }
                }
                
                print(f"调用generate_guidance接口: {guidance_url}")
                guidance_response = requests.post(guidance_url, json=guidance_payload, timeout=120)
                
                if guidance_response.status_code == 200:
                    guidance_result = guidance_response.json()
                    guidance_text = guidance_result.get('output', '')
                    print(f"从generate_guidance获取的引导内容: {guidance_text}")
                else:
                    raise Exception(f"generate_guidance接口调用失败，状态码：{guidance_response.status_code}")
                    
            except Exception as guidance_error:
                print(f"generate_guidance接口调用失败: {str(guidance_error)}")
                # 如果接口调用失败，使用默认引导内容
                guidance_text = f"关于{event}的引导内容，引导方向：{guideline}"
                print(f"使用默认引导内容: {guidance_text}")
            
            # 第二步：调用generate_t2i_prompt接口生成图片提示词
            try:
                t2i_prompt_url = "http://localhost:25602/generate-t2i-prompt/invoke"
                t2i_prompt_payload = {
                    "input": {
                        "comment": misconception,  # 用户观点作为comment
                        "guideline": guidance_text  # 引导内容作为guideline
                    }
                }
                
                print(f"调用generate_t2i_prompt接口: {t2i_prompt_url}")
                print(f"发送的数据: comment={misconception}, guideline={guidance_text}")
                t2i_prompt_response = requests.post(t2i_prompt_url, json=t2i_prompt_payload, timeout=120)
                
                if t2i_prompt_response.status_code == 200:
                    t2i_prompt_result = t2i_prompt_response.json()
                    print(f"generate_t2i_prompt完整响应: {t2i_prompt_result}")
                    print(f"响应类型: {type(t2i_prompt_result)}")
                    
                    # 根据实际输出格式，提取prompt字段
                    if isinstance(t2i_prompt_result, dict) and 'output' in t2i_prompt_result:
                        prompt = t2i_prompt_result['output']
                    elif isinstance(t2i_prompt_result, str):
                        prompt = t2i_prompt_result
                    else:
                        # 兜底处理：转换为字符串
                        prompt = str(t2i_prompt_result)
                    
                    print(f"从generate_t2i_prompt获取的prompt: {prompt}")
                else:
                    raise Exception(f"generate_t2i_prompt接口调用失败，状态码：{t2i_prompt_response.status_code}")
                    
            except Exception as t2i_prompt_error:
                print(f"generate_t2i_prompt接口调用失败: {str(t2i_prompt_error)}")
                # 如果接口调用失败，使用默认prompt
                prompt = f"Create an image about {event} with guideline {guideline} addressing misconception {misconception}"
                print(f"使用默认prompt: {prompt}")
            
            # 第三步：使用生成的prompt调用图片生成API
            try:
                # 调用本地图片生成接口
                api_url = "http://localhost:25603/generate"
                
                # 准备请求数据
                api_payload = {"prompt": prompt}
                
                print(f"调用图片生成API: {api_url}")
                print(f"使用的prompt: {prompt}")
                
                # 发送POST请求
                api_response = requests.post(api_url, json=api_payload, timeout=120)
                
                if api_response.status_code == 200:
                    # 从API获取返回的Base64编码的图片
                    image_b64 = api_response.json().get("image_b64")
                    if image_b64:
                        img_base64 = image_b64
                        is_fallback_image = False
                        print("图片生成成功！")
                    else:
                        raise Exception("API响应中没有找到图片数据")    
                else:
                    print(f"API请求失败，状态码：{api_response.status_code}")
                    raise Exception(f"API请求失败，状态码：{api_response.status_code}")
                    
            except Exception as api_error:
                # 如果API调用出错，创建示例图片
                print(f"图片生成API调用失败，使用示例图片: {str(api_error)}")
                img = Image.new('RGB', (512, 512), color='lightblue')
                img_io = io.BytesIO()
                img.save(img_io, 'PNG')
                img_io.seek(0)
                img_base64 = base64.b64encode(img_io.getvalue()).decode()
                is_fallback_image = True
        
        # 保存图片到本地文件（只有在调用大模型生成时才保存）
        if image_source == "generated":
            try:
                # 生成唯一的文件名
                timestamp = int(time.time())
                image_filename = f"{timestamp}.png"
                
                # 确保 t2i-images 文件夹存在
                algorithm_dir = os.path.join(os.path.dirname(__file__), 'algorithm')
                images_dir = os.path.join(algorithm_dir, 't2i-images')
                os.makedirs(images_dir, exist_ok=True)
                
                # 保存图片文件
                image_path = os.path.join(images_dir, image_filename)
                img_bytes = base64.b64decode(img_base64)
                with open(image_path, 'wb') as f:
                    f.write(img_bytes)
                
                # 保存记录到 JSON 文件
                save_to_t2i_records(event, guideline, misconception, prompt, image_filename, guidance_text)
                
                print(f"新生成的图片已保存到: {image_path}")
                
            except Exception as save_error:
                print(f"保存图片失败: {str(save_error)}")
        else:
            print("使用本地已有图片，无需保存新文件")

        return JsonResponse({
            'success': True,
            'message': '图片获取成功' if image_source == "local" else ('图片生成成功' if not is_fallback_image else '使用示例图片（真实图片生成失败）'),
            'text': guidance_text,
            'image': img_base64,
            'image_format': 'data:image/png;base64,',
            'is_fallback': is_fallback_image,
            'api_status': 'success' if not is_fallback_image else 'fallback',
            'image_source': image_source,
            'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')  # 返回记录创建时间
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'error': f'图片生成失败: {str(e)}'
        }, status=500)


def save_to_t2i_records(event, guideline, misconception, prompt, image_filename, guidance_text):
    """保存图片生成记录到 t2i-recoreds.json 文件，使用opinion作为key"""
    try:
        # 获取 algorithm 文件夹的路径
        algorithm_dir = os.path.join(os.path.dirname(__file__), 'algorithm')
        json_file_path = os.path.join(algorithm_dir, 't2i-recoreds.json')
        
        # 读取现有记录
        if os.path.exists(json_file_path):
            with open(json_file_path, 'r', encoding='utf-8') as f:
                records = json.load(f)
        else:
            records = {}  # 改为字典格式
        
        # 使用opinion作为key，保存完整信息
        records[misconception] = {
            "text": guidance_text,
            "prompt": prompt,            # 提示词作为text
            "image": f"./t2i-images/{image_filename}",  # 图片路径
            "event": event,            # 事件主题
            "guideline": guideline,    # 引导方向
            "timestamp": time.strftime('%Y-%m-%d %H:%M:%S')  # 记录创建时间
        }
        
        # 保存回文件
        with open(json_file_path, 'w', encoding='utf-8') as f:
            json.dump(records, f, ensure_ascii=False, indent=2)
        
        print(f"图片生成记录已保存到: {json_file_path}")
        return True
        
    except Exception as e:
        print(f"保存记录失败: {str(e)}")
        return False

